local module = {}
module.name = "Raid"
module.Init = function()
	if not SCDB.modules[module.name] then return end
   
   SetCVar("raidFramesDisplayAggroHighlight", 1)
   SetCVar("raidFramesDisplayClassColor", 1)
   SetCVar("raidOptionShowBorders", 0)

   local important = {
      -- Crowd control
      [GetSpellInfo(2637)] 	    = 3,	-- Hibernate
      [GetSpellInfo(55041)] 	= 3, 	-- Freezing Trap Effect
      [GetSpellInfo(5782)]	    = 3, 	-- Fear
      [GetSpellInfo(6789)]	    = 3,	-- Death Coil Warlock
      [GetSpellInfo(6358)] 	    = 3, 	-- Seduction
      [GetSpellInfo(5484)] 	    = 3, 	-- Howl of Terror
      [GetSpellInfo(8122)] 	    = 3,	-- Psychic Scream
      [GetSpellInfo(118)] 	    = 3,	-- Polymorph
      [GetSpellInfo(28272)] 	= 3,	-- Polymorph pig
      [GetSpellInfo(28271)] 	= 3,	-- Polymorph turtle
      [GetSpellInfo(61305)] 	= 3,	-- Polymorph black cat
      [GetSpellInfo(61025)] 	= 3,	-- Polymorph serpent
      [GetSpellInfo(51514)]	    = 3,	-- Hex

      -- Roots
      [GetSpellInfo(339)] 	    = 3, 	-- Entangling Roots
      [GetSpellInfo(122)]		= 3,	-- Frost Nova
      [GetSpellInfo(13809)] 	= 1, 	-- Frost Trap

      -- Stuns and incapacitates
      [GetSpellInfo(44572)]	    = 3, 	-- Deep Freeze
      [GetSpellInfo(19386)]	    = 3, 	-- Wyvern Sting
      [GetSpellInfo(853)]		= 3, 	-- Hammer of Justice
      [GetSpellInfo(20066)] 	= 3, 	-- Repentance
      [GetSpellInfo(49203)] 	= 3,	-- Hungering Cold

      -- Silences
      [GetSpellInfo(18469)] 	= 1,	-- Improved Counterspell
      [GetSpellInfo(15487)] 	= 1, 	-- Silence
      [GetSpellInfo(34490)] 	= 1, 	-- Silencing Shot	
      [GetSpellInfo(47476)]	    = 1,	-- Strangulate
      
   }
   
   local CanDispel = {
      PRIEST = { Magic = true, Disease = true, },
      SHAMAN = { Magic = true, Curse = true, },
      PALADIN = { Magic = true, Poison = true, Disease = true, },
      MAGE = { Curse = true, },
      DRUID = { Magic = true, Curse = true, Poison = true, }
   }
   
   local dispellist = CanDispel[select(2,UnitClass("player"))] or {}
   
   local function GetDebuffType(unit)
      if not unit then return end
      if not UnitCanAssist("player", unit) then return nil end
      local i = 1
      
      local ua = GetSpellInfo(30108) -- Unstable Affliction
      local _, _, texture, _, debufftype, _, _, _, _, _, spellId = UnitAura(unit, ua)
      if spellId then
         return 'unstable', texture, 99
      end
      
      while true do
         local _, _, texture, _, debufftype, _, _, _, _, _, spellId = UnitAura(unit, i, "HARMFUL")
         if not texture then break end
         if debufftype and spellId and dispellist[debufftype] and important[GetSpellInfo(spellId)] then
            return debufftype, texture, important[GetSpellInfo(spellId)]
         end
         i = i + 1
      end
      
      i = 1
      while true do
         local _, _, texture, _, debufftype = UnitAura(unit, i, "HARMFUL")
         if not texture then break end
         if debufftype and dispellist[debufftype] then
            return debufftype, texture, 0
         end
         i = i + 1
      end
   end
   
   if SCDB[module.name] == nil then SCDB[module.name] = {} end
   
   local Texture_SetSize = ActionButton1Icon.SetSize
   local fixedFrames = {}
   
   function styleCompactFrame(frame)
      frame:RegisterForDrag("LeftButton")
      frame:SetScript("OnDragStart", function(self)
         if (self:GetParent().movable ) then
            CompactRaidGroup_StartMoving(self:GetParent())
         else
            CompactRaidFrameManager_ResizeFrame_OnDragStart(CompactRaidFrameManagerContainerResizeFrameMover:GetParent():GetParent())
         end         
      end)
      frame:SetScript("OnDragStop", function(self)
         if (self:GetParent().movable ) then
            CompactRaidGroup_StopMoving(self:GetParent())
         else
            CompactRaidFrameManager_ResizeFrame_OnDragStop(CompactRaidFrameManagerContainerResizeFrameMover:GetParent():GetParent())
         end         
      end)
      
      frame.name:SetFontObject(NumberFontNormal)
      frame.name:ClearAllPoints()
      frame.name:SetPoint("CENTER")
      
      local buffs = frame.buffFrames
      local debuffs = frame.debuffFrames
      local d_debuffs = frame.dispelDebuffFrames
      
      for i=1,3 do
         Texture_SetSize(buffs[i], 12, 12)
         Texture_SetSize(debuffs[i], 24, 24)
         Texture_SetSize(d_debuffs[i], 12, 12)
         debuffs[i]:ClearAllPoints()
         debuffs[i]:SetPoint("CENTER")
         debuffs[i].noOCC = true
         if not buffs[i].bg then
            buffs[i].icon:SetTexCoord(.1,.9,.1,.9)
            buffs[i].icon:SetPoint("TOPLEFT", 1, -1)
            buffs[i].icon:SetPoint("BOTTOMRIGHT", -1, 1)
            buffs[i].bg = buffs[i]:CreateTexture(nil, "BORDER")
            buffs[i].bg:SetAllPoints(buffs[i])
            buffs[i].bg:SetTexture(0,0,0,1)
         end
      end
      
      buffs[1]:ClearAllPoints()
      buffs[1]:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1)

      frame.background:SetTexture(0,0,0,.5)
      frame.healthBar:SetStatusBarTexture("Interface\\Addons\\"..addonName.."\\media\\texture\\statusbar", "BORDER")
      
      frame.statusText:SetFont("Fonts\\ARIALN.ttf", 10, "OVERLAY")
      frame.statusText:ClearAllPoints()
      frame.statusText:SetPoint("BOTTOM")
      
      if not fixedFrames[frame] then
         fixedFrames[frame] = true

         frame.raidIcon = frame:CreateTexture(frame:GetName().."RaidTarget", "OVERLAY")
         frame.raidIcon:SetWidth(16)
         frame.raidIcon:SetHeight(16)
         frame.raidIcon:SetPoint("TOPRIGHT", -2, -2)
         frame.raidIcon:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcons")
         frame.raidIcon:Hide()
         
         frame.DebuffHighlight = frame:CreateTexture(frame:GetName().."RaidDebuffIcon", "OVERLAY")
         frame.DebuffHighlight:SetWidth(26)
         frame.DebuffHighlight:SetHeight(26)
         frame.DebuffHighlight:SetPoint("CENTER")
         
         -- make debuffs 12x12
         for i=1,3 do
            hooksecurefunc(debuffs[i], "SetSize", function(debuffFrame) 
               debuffFrame:Hide()
            end)
         end
      end
   end

   local showRaidIcon = function(self)
      if not self.unit then return end
      local index = GetRaidTargetIndex(self.unit)
      local icon = self.raidIcon
      if index then
         SetRaidTargetIconTexture(icon, index)
         icon:Show()
         CompactUnitFrame_UpdateAll(self)
      else
         icon:Hide()
      end
   end
   
   local showDebuff = function(self)
      if not self.unit then return end
      local debuffType, texture, priority = GetDebuffType(self.unit)
      if self.DebuffHighlight then
         if  debuffType and debuffType:lower():find("unstable") then
            self.DebuffHighlight:SetTexture(texture)
            self.DebuffHighlight:SetDesaturated(1)
         elseif debuffType and not debuffType:lower():find("unstable") then
            self.DebuffHighlight:SetDesaturated(0)
            self.DebuffHighlight:SetTexture(texture)
         else
            self.DebuffHighlight:SetTexture(nil)
         end
      end
   end

   hooksecurefunc("CompactUnitFrame_SetUnit", function(self, unit)
      showRaidIcon(self)
      
      self:HookScript("OnEvent", function(self, event, ...)
         local arg1, arg2, arg3, arg4 = ...

         if not self:IsEventRegistered("PLAYER_ENTERING_WORLD") then
            self:RegisterEvent("PLAYER_ENTERING_WORLD")
         end
         if not self:IsEventRegistered("RAID_TARGET_UPDATE") then
            self:RegisterEvent("RAID_TARGET_UPDATE")
         end

         if ( event == "RAID_TARGET_UPDATE") then
            showRaidIcon(self)
         elseif (event == "PLAYER_ENTERING_WORLD") then
            showRaidIcon(self)
         end
      end)
      
   end)
   
   hooksecurefunc("CompactUnitFrame_UpdateDispellableDebuffs", function(self)
      showDebuff(self)
   end)
   
   hooksecurefunc("CompactUnitFrame_UpdateDebuffs", function(self)
      showDebuff(self)
   end)
   
   hooksecurefunc("DefaultCompactUnitFrameSetup", styleCompactFrame)
   hooksecurefunc("DefaultCompactMiniFrameSetup", styleCompactFrame)
   hooksecurefunc("CompactRaidFrameReservation_RegisterReservation", function(_, frame, _) styleCompactFrame(frame) end)

   hooksecurefunc("CompactUnitFrame_UpdateName", function(self)
      if self.name and self.name:GetText() then
         if #self.name:GetText() > 8 then
            self.name:SetText(self.name:GetText():sub(1,8))
         end
      end
   end)

   hooksecurefunc("CompactRaidFrameManager_UpdateContainerBounds", function(frame)
      frame.containerResizeFrame:SetMaxResize(frame.containerResizeFrame:GetWidth(), (GetScreenHeight()*2) - 90)
   end)

   hooksecurefunc("CompactRaidFrameManager_ResizeFrame_CheckMagnetism", function(manager)
      local point, relativeTo, relativePoint, xOffset, yOffset = manager.containerResizeFrame:GetPoint(1)
      if relativeTo == manager then
         CompactRaidFrameManager_ResetContainerPosition()
      end
   end)
   
end
tinsert(SuperClassic.modules, module) -- finish him!